package com.itlong.cloud.property.service.impl;

import com.itlong.cloud.POJO.DTO.app.APPServiceTemporaryCarListPageDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateFixedVehiclePageDTO;
import com.itlong.cloud.POJO.DTO.property.CarIssueDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyCarOpenMonthCardDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyCarRenewMonthCardDTO;
import com.itlong.cloud.POJO.PO.PropertyCarManagePO;
import com.itlong.cloud.POJO.PO.PropertyCardPaymentRecordPO;
import com.itlong.cloud.POJO.PO.PropertyPaymentBillPO;
import com.itlong.cloud.POJO.VO.app.AppServiceTemporaryCarListVO;
import com.itlong.cloud.POJO.VO.operate.OperateFixedVehicleInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyCarGetOneVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.property.dao.IPropertyCarDao;
import com.itlong.cloud.property.dao.IPropertyCarMonthCardDao;
import com.itlong.cloud.property.service.IPropertyAccountService;
import com.itlong.cloud.property.service.IPropertyCarMonthCardService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      物业管理-车辆的月卡管理服务接口实现类
 * </desc>
 *
 * @createDate 2018/11/05
 */
@Service
public class PropertyCarMonthCardServiceImpl implements IPropertyCarMonthCardService {

    @Autowired
    private IPropertyCarMonthCardDao iPropertyCarMonthCardDao;

    @Autowired
    private IPropertyCarDao iPropertyCarDao;

    @Autowired
    private RedisService redisService;

    @Autowired
    IPropertyAccountService iPropertyAccountService;

    /**
     * <desc>
     *      车辆开通或修改月卡
     * </desc>
     *
     * @param propertyCarOpenMonthCardDTO 月卡开通、修改DTO
     * @return 受影响行数
     * @throws Exception
     * @author wangzhi
     * @createDate 2018/11/05
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer openMonthCard(PropertyCarOpenMonthCardDTO propertyCarOpenMonthCardDTO) throws Exception {
        PropertyCarManagePO propertyCarManagePO = new PropertyCarManagePO();
        propertyCarManagePO.setCarId(propertyCarOpenMonthCardDTO.getCarId());
        propertyCarManagePO.setMonthCardId(propertyCarOpenMonthCardDTO.getMonthCardId());
        propertyCarManagePO.setOwnerPhone(propertyCarOpenMonthCardDTO.getOwnerPhone());
        Map<String,Object> map = SqlUtil.durableData(propertyCarManagePO, PlatformConstants.TABLE_UPDATE);
        return iPropertyCarMonthCardDao.openMonthCard(map);
    }

    /**
     * <desc>
     *      车辆月卡续费
     * </desc>
     *
     * @param propertyCarRenewMonthCardDTO 月卡续费DTO
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/11/05
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public CarIssueDTO renewMonthCard(PropertyCarRenewMonthCardDTO propertyCarRenewMonthCardDTO, String mark) throws Exception{
        if ("1".equals(mark)) {
            return getCarIssueDTO(propertyCarRenewMonthCardDTO);
        }
        Date nowTime = new Date();
        // 生成账单并保存
        PropertyPaymentBillPO propertyPaymentBillPO = new PropertyPaymentBillPO();
        propertyPaymentBillPO.setFeeId(LogicIdUtil.bussinessId());
        // 生成费用单号 规则年月日+六位流水号，如180720000001
        String date = DateUtil.fomatDate(new Date(),"yyMMdd");
        //从缓存中获取流水号
        String redisKey = RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE+propertyCarRenewMonthCardDTO.getProjectId()+date;
        Integer tradeNo = (Integer)redisService.getObject(redisKey, Integer.class);
        if(tradeNo == null){
            //查询数据库中是否有当前流水号，有的话将当前流水号放入缓存中且+1赋值给tradeNo
            String feeNumber = iPropertyCarMonthCardDao.getFeeNumberByDate(DateUtil.fomatDate(new Date(),"yyyy-MM-dd"),propertyCarRenewMonthCardDTO.getProjectId());
            if(StringUtils.isBlank(feeNumber)){
                tradeNo = 1;
            }else{
                tradeNo = Integer.valueOf(feeNumber);
                tradeNo += 1;
            }
        }else{
            tradeNo+=1;
        }
        redisService.set(redisKey,RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE_TIME,tradeNo);
        propertyPaymentBillPO.setFeeNumber(date+StringHandlerUtil.autlSupply(6,tradeNo.toString(),"0"));
        Map<String,Object> getCarMap = new HashMap<>();
        getCarMap.put("carId",propertyCarRenewMonthCardDTO.getCarId());
        getCarMap.put("projectId",propertyCarRenewMonthCardDTO.getProjectId());
        PropertyCarGetOneVO oneBasicCar = iPropertyCarDao.getOneBasicCar(getCarMap);
        propertyPaymentBillPO.setBuildId(oneBasicCar.getBuildId());
        propertyPaymentBillPO.setUnitId(oneBasicCar.getUnitId());
        propertyPaymentBillPO.setRoomId(oneBasicCar.getRoomId());
        propertyPaymentBillPO.setPhoneNum(oneBasicCar.getOwnerPhone());
        propertyPaymentBillPO.setRealName(oneBasicCar.getOwnerName());
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(nowTime);
        cal1.set(Calendar.DAY_OF_MONTH,1);
        cal1.add(Calendar.MONTH, 0);
        propertyPaymentBillPO.setStartTime(cal1.getTime());
        Calendar cal2 = Calendar.getInstance();
        cal2.set(Calendar.DAY_OF_MONTH, cal2.getActualMaximum(Calendar.DAY_OF_MONTH));
        propertyPaymentBillPO.setEndTime(cal2.getTime());
        propertyPaymentBillPO.setType(3);
        propertyPaymentBillPO.setDueAmount(new BigDecimal(propertyCarRenewMonthCardDTO.getPaidAmount()));
        propertyPaymentBillPO.setPaidAmount(new BigDecimal(propertyCarRenewMonthCardDTO.getPaidAmount()));
        propertyPaymentBillPO.setPenalty(new BigDecimal("0"));
        propertyPaymentBillPO.setProjectId(propertyCarRenewMonthCardDTO.getProjectId());
        propertyPaymentBillPO.setFeeStatus(2);
        propertyPaymentBillPO.setPaymentType(propertyCarRenewMonthCardDTO.getPaymentType());
        propertyPaymentBillPO.setOriginPay(1);
        propertyPaymentBillPO.setPayTime(nowTime);
        propertyPaymentBillPO.setUserId(propertyCarRenewMonthCardDTO.getLoginUserId());
        propertyPaymentBillPO.setStatus(DataStatusEnum.NORMAL.getType());
        propertyPaymentBillPO.setCreateTime(nowTime);
        propertyPaymentBillPO.setUpdateTime(nowTime);
        iPropertyCarMonthCardDao.save(SqlUtil.durableData(propertyPaymentBillPO,PlatformConstants.TABLE_SAVE));

        // 保存月卡缴费记录之前先查询该车辆是否有开通过月卡
//        Integer recordCount = iPropertyCarMonthCardDao.getRenewMonthCardRecordCount(propertyCarRenewMonthCardDTO.getCarId(),propertyCarRenewMonthCardDTO.getProjectId());

        // 保存月卡缴费记录
        PropertyCardPaymentRecordPO propertyCardPaymentRecordPO = new PropertyCardPaymentRecordPO();
        propertyCardPaymentRecordPO.setCarId(propertyCarRenewMonthCardDTO.getCarId());
        propertyCardPaymentRecordPO.setMonthCardId(propertyCarRenewMonthCardDTO.getMonthCardId());
        propertyCardPaymentRecordPO.setFeeId(propertyPaymentBillPO.getFeeId());
        propertyCardPaymentRecordPO.setProjectId(propertyCarRenewMonthCardDTO.getProjectId());
        String endTimeAgoString = iPropertyCarMonthCardDao.getEndTimeAgo(propertyCarRenewMonthCardDTO.getCarId(),propertyCarRenewMonthCardDTO.getProjectId());
        Date endTimeAgo;
        if (StringUtils.isNotBlank(endTimeAgoString)) {
            endTimeAgo = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(endTimeAgoString);
        } else {
            endTimeAgo = nowTime;
        }
        propertyCardPaymentRecordPO.setStartTime(endTimeAgo);
        cal1.setTime(endTimeAgo);
        cal1.add(Calendar.MONTH,propertyCarRenewMonthCardDTO.getMonth());
        propertyCardPaymentRecordPO.setEndTime(cal1.getTime());
        propertyCardPaymentRecordPO.setMonth(propertyCarRenewMonthCardDTO.getMonth());
        propertyCardPaymentRecordPO.setStatus(DataStatusEnum.NORMAL.getType());
        propertyCardPaymentRecordPO.setCreateTime(nowTime);
        propertyCardPaymentRecordPO.setUpdateTime(nowTime);
        iPropertyCarMonthCardDao.save(SqlUtil.durableData(propertyCardPaymentRecordPO,PlatformConstants.TABLE_SAVE));

        // 返回数据
        CarIssueDTO carIssueDTO = new CarIssueDTO();
//        cal1.setTime(propertyCardPaymentRecordPO.getStartTime());
//        cal1.set(Calendar.HOUR_OF_DAY,0);
//        cal1.set(Calendar.MINUTE,0);
//        cal1.set(Calendar.SECOND,0);
//        carIssueDTO.setBeginDate(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).format(cal1.getTime()));
//        cal1.setTime(propertyCardPaymentRecordPO.getEndTime());
//        cal1.set(Calendar.HOUR_OF_DAY,23);
//        cal1.set(Calendar.MINUTE,59);
//        cal1.set(Calendar.SECOND,59);
//        carIssueDTO.setEndDate(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).format(cal1.getTime()));
//        carIssueDTO.setPlate(oneBasicCar.getPlateNumber());
//        carIssueDTO.setMoney(new BigDecimal(propertyCarRenewMonthCardDTO.getPaidAmount()));
//        if (recordCount > 0) { // 1开卡 2续卡
//            carIssueDTO.setType(2);
//        } else {
//            carIssueDTO.setType(1);
//        }
//        carIssueDTO.setPayType(propertyCarRenewMonthCardDTO.getPaymentType());
//        carIssueDTO.setProjectId(propertyCarRenewMonthCardDTO.getProjectId());
        return carIssueDTO;
    }

    /**
     * <desc>
     *      获取车牌凭证发行dto对象
     * </desc>
     *
     * @return 车牌凭证发行dto对象
     * @author wangzhi
     * @createDate 2018/12/13
     */
    public CarIssueDTO getCarIssueDTO(PropertyCarRenewMonthCardDTO propertyCarRenewMonthCardDTO) throws Exception{
        // 返回数据
        Calendar cal1 = Calendar.getInstance();
        Map<String,Object> getCarMap = new HashMap<>();
        getCarMap.put("carId",propertyCarRenewMonthCardDTO.getCarId());
        getCarMap.put("projectId",propertyCarRenewMonthCardDTO.getProjectId());
        PropertyCarGetOneVO oneBasicCar = iPropertyCarDao.getOneBasicCar(getCarMap);
        // 先查询该车辆是否有开通过月卡
        Integer recordCount = iPropertyCarMonthCardDao.getRenewMonthCardRecordCount(propertyCarRenewMonthCardDTO.getCarId(),propertyCarRenewMonthCardDTO.getProjectId());
        CarIssueDTO carIssueDTO = new CarIssueDTO();
        String endTimeAgoString = iPropertyCarMonthCardDao.getEndTimeAgo(propertyCarRenewMonthCardDTO.getCarId(),propertyCarRenewMonthCardDTO.getProjectId());
        Date endTimeAgo;
        if (StringUtils.isNotBlank(endTimeAgoString)) {
            endTimeAgo = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).parse(endTimeAgoString);
        } else {
            endTimeAgo = new Date();
        }
        cal1.setTime(endTimeAgo);
        cal1.set(Calendar.HOUR_OF_DAY,0);
        cal1.set(Calendar.MINUTE,0);
        cal1.set(Calendar.SECOND,0);
        carIssueDTO.setBeginDate(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).format(cal1.getTime()));
        cal1.add(Calendar.MONTH,propertyCarRenewMonthCardDTO.getMonth());
        cal1.set(Calendar.HOUR_OF_DAY,23);
        cal1.set(Calendar.MINUTE,59);
        cal1.set(Calendar.SECOND,59);
        carIssueDTO.setEndDate(new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1).format(cal1.getTime()));
        carIssueDTO.setPlate(oneBasicCar.getPlateNumber());
        carIssueDTO.setMoney(new BigDecimal(propertyCarRenewMonthCardDTO.getPaidAmount()));
        if (recordCount > 0) { // 1开卡 2续卡
            carIssueDTO.setType(2);
        } else {
            carIssueDTO.setType(1);
        }
        Integer payType = 12;
        switch (propertyCarRenewMonthCardDTO.getPaymentType()) { // 收费方式：1现金 2银行转账 3支付宝转账 4微信转账 5小区收款码-微信 6小区收款码-支付宝 7其他支付方式
            case 1:
                payType = 3;
                break;
            case 2:
                break;
            case 3:
                payType = 5;
                break;
            case 4:
                payType = 2;
                break;
            case 5:
                payType = 2;
                break;
            case 6:
                payType = 5;
                break;
            case 7:
                break;
            default:
                break;
        }
        carIssueDTO.setPayType(payType);
        carIssueDTO.setProjectId(propertyCarRenewMonthCardDTO.getProjectId());
        return carIssueDTO;
    }

    /**
     * <desc>
     *      固定车辆信息分页查询
     * </desc>
     *
     * @param operateFixedVehiclePageDTO 分页查询参数
     * @return
     * @author Qiang.S
     * @createDate 2018/11/05
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Page<OperateFixedVehicleInfoVO> getFixedVehiclePage(OperateFixedVehiclePageDTO operateFixedVehiclePageDTO) throws Exception{
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operateFixedVehiclePageDTO);
        //分页类默认pageSize为20
        Page<OperateFixedVehicleInfoVO> page = new Page<>();
        page.getPage().setPageSize(operateFixedVehiclePageDTO.getPageSize());
        page.getPage().setCurrentPage(operateFixedVehiclePageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        page.setRows(iPropertyCarMonthCardDao.getFixedVehiclePage(params),iPropertyCarMonthCardDao.getFixedVehicleCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取临时车辆列表
     * </desc>
     *
     * @param appServiceTemporaryCarListPageDTO
     * @return
     * @author Qiang.S
     * @createDate 2018/11/07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Page<AppServiceTemporaryCarListVO> temporaryCarList(APPServiceTemporaryCarListPageDTO appServiceTemporaryCarListPageDTO) throws Exception{
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(appServiceTemporaryCarListPageDTO);
        //分页类默认pageSize为20
        Page<AppServiceTemporaryCarListVO> page = new Page<>();
        page.getPage().setPageSize(appServiceTemporaryCarListPageDTO.getPageSize());
        page.getPage().setCurrentPage(appServiceTemporaryCarListPageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        List<AppServiceTemporaryCarListVO> list = iPropertyCarMonthCardDao.temporaryCarList(params);
        //看自己的时间格式选择对应的转换对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime = DateUtil.fomatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
        for (AppServiceTemporaryCarListVO appServiceTemporaryCarListVO:list) {
            if ("1".equals(appServiceTemporaryCarListVO.getIsParking())) {
                if (appServiceTemporaryCarListVO.getParkingTime() ==null || !"".equals(appServiceTemporaryCarListVO.getParkingTime())) {
                    String startTime = appServiceTemporaryCarListVO.getInTime();
                    //转换成date类型
                    Date start = sdf.parse(startTime);
                    Date end = sdf.parse(endTime);
                    //获取毫秒数
                    Long startLong = start.getTime();
                    Long endLong = end.getTime();
                    //计算时间差,单位毫秒
                    Long ms = endLong-startLong;
                    appServiceTemporaryCarListVO.setParkingTime(this.longTimeToDay(ms));
                }
            }
        }
        page.setRows(list,iPropertyCarMonthCardDao.temporaryCarCount(params));
        return page;
    }

    /**
     * <desc>
     *      删除临时车辆通行记录
     * </desc>
     *
     * @param plateNumber 车牌
     * @param userId 用户编号
     * @return
     * @author Qiang.S
     * @createDate 2018/11/07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer deleteTemporaryCar(String plateNumber, String userId) throws Exception{
        return iPropertyCarMonthCardDao.deleteTemporaryCar(plateNumber, userId);
    }

    /**
     * <desc>
     *      清除临时车辆列表
     * </desc>
     *
     * @param userId 用户编号
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2019/06/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer deleteAllTemporaryCar(String userId) throws Exception {
        return iPropertyCarMonthCardDao.deleteAllTemporaryCar(userId);
    }

    /**
     * <desc>
     *      处理时间差格式化方法
     * </desc>
     *
     * @param ms 时间差
     * @return 时间格式化结果
     * @author Qiang.S
     * @createDate 2018/11/16
     */
    private String longTimeToDay(Long ms){
        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh;
        Long minute = (ms - day * dd - hour * hh) / mi;
        Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        StringBuffer sb = new StringBuffer();
        if(day > 0) {
            sb.append(day+"天");
        }
        if(hour > 0) {
            sb.append(hour+"小时");
        }
        if(minute > 0) {
            sb.append(minute+"分");
        }
        if(second > 0) {
            sb.append(second+"秒");
        }
        if(milliSecond > 0) {
            sb.append(milliSecond+"毫秒");
        }
        return sb.toString();
    }

}
